package com.example.mybatisdemo.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.*;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

/**
 * describe:配置类
 *
 * @author xugang
 * @date 2019/1/3 15:41
 */
@Configuration
@EnableAutoConfiguration
@MapperScan(value = "com.example.mybatisdemo.mapper")
public class AppConfiguration {
    private static final String DB_PREFIX = "spring.datasource.";

    @Value("${jdbc.druid.loginUsername:root}")
    private String loginUsername;
    @Value("${jdbc.druid.loginPassword:12345}")
    private String loginPassword;

    @Autowired
    private Environment environment;

    @Bean
    @ConfigurationProperties(prefix = DB_PREFIX)
    public DataSource druidDataSource() throws SQLException {
        Properties dbProperties = new Properties();
        Map<String, Object> map = new HashMap<String, Object>();
        Iterator<PropertySource<?>> it = ((AbstractEnvironment) environment).getPropertySources().iterator();
        while (it.hasNext()) {
            PropertySource<?> propertySource = it.next();
            getPropertiesFromSource(propertySource, map);
        }
        dbProperties.putAll(map);

        DruidDataSource dds = null;
        try {
            dds = (DruidDataSource) DruidDataSourceFactory.createDataSource(dbProperties);
            dds.init();
        } catch (Exception e) {
            throw new RuntimeException("load datasource error, dbProperties is :" + dbProperties, e);
        }
        dds.setFilters("wall,stat");
        return dds;
    }

    /**
     * 获取类型为MapPropertySource的属性信息，并封装到map对象中
     *
     * @param propertySource
     * @param map
     */
    private void getPropertiesFromSource(PropertySource<?> propertySource, Map<String, Object> map) {
        if (propertySource instanceof MapPropertySource) {
            for (String key : ((MapPropertySource) propertySource).getPropertyNames()) {
                if (key.startsWith(DB_PREFIX)) {
                    System.out.println("============= propertySource = [" + propertySource + "], key = [" + key + "]");
                    map.put(key.replaceFirst(DB_PREFIX, ""), propertySource.getProperty(key));
                }
            }
        }
        if (propertySource instanceof CompositePropertySource) {
            for (PropertySource<?> s : ((CompositePropertySource) propertySource)
                    .getPropertySources()) {
                getPropertiesFromSource(s, map);
            }
        }
    }
}
